﻿#include "SerialClientThread.h"

using namespace FCMiddleware;

SerialClientThread::SerialClientThread(Depacker* depacker, const QString& name, unsigned int baud, QObject *parent)
	: QThread(parent)
{
	_opened = false;
	_portName = name;
	_portBaud = baud;
	_parity = QSerialPort::NoParity;

	_serialClient = NULL;
	_depacker = depacker;

	_isRunning = false;
	_running = false;
}

SerialClientThread::~SerialClientThread()
{
}

void SerialClientThread::setPort(const QString& portName, unsigned int portBaud, QSerialPort::Parity parity)
{
	_portName = portName;
	_portBaud = portBaud;
	_parity = parity;
}

void SerialClientThread::port(QString& portName, unsigned int& portBaud)
{
	portName = _portName;
	portBaud = _portBaud;
}

void SerialClientThread::startServer()
{
	_running = true;
	start();
}

void SerialClientThread::stopServer()
{
	_runLocker.lock();
	_running = false;
	_runLocker.unlock();
	while (_isRunning);
}

void SerialClientThread::run()
{
	_isRunning = true;
	bool runable = true;

	emit stateChanged(ThreadStateType_Running, 0);

	_serialClient = new SerialClient();
	_serialClient->setPortParams(_portName, _portBaud, _parity);
	emit stateChanged(ThreadStateType_Opening, 0);
	int err = _serialClient->open();
	if (err != QSerialPort::NoError)
	{
		delete _serialClient;
		_serialClient = NULL;
		emit stateChanged(ThreadStateType_OpenFailed, err);
	}
	else
	{
		_opened = true;
		emit stateChanged(ThreadStateType_Opened, 0);
	}

	if (!_opened)
	{
		emit stateChanged(ThreadStateType_Quit, 0);
		_isRunning = false;
		return;
	}

	_depacker->clear();

    unsigned int size;
	unsigned char* buf;
	int ret;

	while (1)
	{
		_runLocker.lock();
		runable = _running;
		_runLocker.unlock();

		if (!runable)
			break;

		if (!sendPacket())
			break;

		buf = _depacker->buf(&size);
        ret = _serialClient->recv(buf, size & 0x0000ffff, &err);
		if (ret == -1)
		{
			emit stateChanged(ThreadStateType_ReadFailed, err);
			break;
		}

		if (ret == 0)
			continue;
		else _depacker->push(ret);

		if (!recvCmd())
			break;
	}

	if (_serialClient != NULL)
	{
		_serialClient->close();
		_opened = false;

		emit stateChanged(ThreadStateType_Close, 0);
	}

	emit stateChanged(ThreadStateType_Quit, 0);
	_isRunning = false;
	return;
}

bool SerialClientThread::sendPacket()
{
	Q_ASSERT(_serialClient != NULL);

	return true;
}

bool SerialClientThread::recvCmd()
{
	return true;
}
